/* **********************************************************************
 * Copyright (c) Ericsson 2007. All Rights Reserved.
 * Reproduction in whole or in part is prohibited without the 
 * written consent of the copyright owner. 
 * 
 * ERICSSON MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY 
 * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE, OR NON-INFRINGEMENT. ERICSSON SHALL NOT BE LIABLE FOR ANY 
 * DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. 
 * 
 * **********************************************************************/

package com.ericsson.client;

import java.io.IOException;

import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import javay.microedition.ims.Configuration;
import javay.microedition.ims.ConnectionState;
import javay.microedition.ims.ConnectionStateListener;
import javay.microedition.ims.core.CoreService;
import javay.microedition.ims.core.CoreServiceListener;
import javay.microedition.ims.core.Message;
import javay.microedition.ims.core.PageMessage;
import javay.microedition.ims.core.PageMessageListener;
import javay.microedition.ims.core.Reference;
import javay.microedition.ims.core.Session;
import javay.microedition.io.Connector;

import com.ericsson.ijcu.IjcuUserManagement;

public class IjcuBasicPageMessage extends MIDlet
{
    /**
     * Text area
     */
    private StringItem textArea;

    private TextField domainURIField;

    private TextField outboundProxyURIField;

    private TextField publicUserIdField;

    private TextField realmField;

    private TextField privateUserIdField;

    private TextField mobilePhoneNumberField;

    private TextField passwordField;

    /**
     * Form that allows user to send page messages
     */
    private Form sendMessageForm;

    /**
     * Service Id
     */
    private String scheme = "imscore://";

    private String iari = "com.ericsson.client.IjcuBasicPageMessage";

    private String serviceId = "pageMessage";

    private String aliceUserId = "sip:alice@ericsson.com";

    private String IARI_PREFIX = "urn%3Aurn-xxx%3A";

    private String transport = "tcp";

    private static String contentType = "text/plain";
     

    /**
     * The core service for creating service methods to be sent to remote user.
     */
    private CoreService coreService;

    /**
     * Initialize resources Display main form.
     */
    public void startApp() throws MIDletStateChangeException
    {
        showRegistrationForm();
    }

    private void showRegistrationForm()
    {
        Display display = getDisplay();

        Form registerForm = new Form("Register");

        Command registerCommand = new Command("Register", Command.OK, 1);
        Command exitCommand = new Command("Exit", Command.EXIT, 1);

        registerForm.addCommand(registerCommand);
        registerForm.addCommand(exitCommand);
        display.setCurrent(registerForm);

        domainURIField = new TextField("DomainURI:", "sip:ericsson.com", 40, TextField.ANY);
        outboundProxyURIField = new TextField("OutboundProxyURI:", "sip:127.0.0.1:5081", 40, TextField.ANY);
        publicUserIdField = new TextField("PublicUserId:", aliceUserId, 40, TextField.ANY);
        realmField = new TextField("realm:", "ericsson.com", 40, TextField.ANY);
        privateUserIdField = new TextField("PrivateUserId:", "alice@ericsson.com", 40, TextField.ANY);
        mobilePhoneNumberField = new TextField("MobilePhoneNumber:", "5143457900", 40, TextField.DECIMAL);
        passwordField = new TextField("Password", "alice", 10, TextField.PASSWORD);
        passwordField.setString("alice");

        registerForm.append(domainURIField);
        registerForm.append(outboundProxyURIField);
        registerForm.append(publicUserIdField);
        registerForm.append(realmField);
        registerForm.append(privateUserIdField);
        registerForm.append(mobilePhoneNumberField);
        registerForm.append(passwordField);

        registerForm.setTitle("Page Message Send Client");

        registerForm.setCommandListener(new CommandListener()
        {
            public void commandAction(Command command, Displayable displayable)
            {
                if(command.getCommandType() == Command.OK)
                {
                    RegisterThread registerThread = new RegisterThread();
                    Thread thread = new Thread(registerThread);
                    thread.start();
                }
                else if(command.getCommandType() == Command.EXIT)
                {
                    exit();
                }
            }
        });
    }

    /**
     * Pause the MIDlet
     */
    public void pauseApp()
    {
    }

    /**
     * Destroy the MIDLet
     * 
     * @param unconditional : <code>true</code>: if it's mandatory to destroy the MIDlet <code>false</code>: if it's not mandatory to destroy the
     *            MIDlet.
     */
    public void destroyApp(boolean unconditional)
    {
    }

    /**
     * Thread to unregister the phone and release resources before the MIDlet is destroyed.
     */
    protected class CleanUpThread extends Thread
    {
        /**
         * Un-register the phone, release resources and destroy the MIDlet
         */
        public void run()
        {
            try
            {
            	if (coreService != null)
            	{
            		coreService.close();
            	}
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
        
    /**
     * Thread to register the phone.
     */
    protected class RegisterThread implements Runnable
    {

        public void run()
        {
            register();
        }

        
        public void register()
        {
            try
            {            	
            	IjcuUserManagement ijcuUserManagement =  IjcuUserManagement.getInstance();            	            
            	ijcuUserManagement.setDomainURI(domainURIField.getString());            	
            	ijcuUserManagement.setOutboundProxyURI(outboundProxyURIField.getString());
            	ijcuUserManagement.setPublicUserId(publicUserIdField.getString());            	
            	ijcuUserManagement.setRealm(realmField.getString());
            	ijcuUserManagement.setPrivateUserId(privateUserIdField.getString());
            	ijcuUserManagement.setPassword(passwordField.getString());
            	ijcuUserManagement.setTransport(transport);            	            	
            	ijcuUserManagement.setPlatform(IjcuBasicPageMessage.this);
            	
            	            	
                Configuration myConfiguration = Configuration.getConfiguration();
                String[][] properties = new String[][] {{ "Framed", contentType },
                                                        { "CoreService", serviceId, IARI_PREFIX + iari, "", "" } };
                myConfiguration.setRegistry(iari, IjcuBasicPageMessage.class.getName(), properties);

                
                ConnectionState connectionState = ConnectionState.getConnectionState();
                connectionState.setListener(new ConnectionStateAdapter());

                
                String url = scheme + iari + ";serviceId=" + serviceId;                
                coreService = (CoreService) Connector.open(url);
                CoreServiceClientAdapter coreServiceAdapter = new CoreServiceClientAdapter();
                coreService.setListener(coreServiceAdapter);

                
                sendMessageForm = new Form("Send a page message");
                final TextField uri = new TextField("\r\nPlease enter the remote URI:", aliceUserId, 40, TextField.ANY);
                Command sendCommand = new Command("Send", Command.OK, 1);
                Command exitCommand = new Command("Exit", Command.EXIT, 1);
                sendMessageForm.addCommand(sendCommand);
                sendMessageForm.addCommand(exitCommand);
                sendMessageForm.append(uri);
                final TextField messageField = new TextField("Enter Message", "hello!", 40, TextField.ANY);
                sendMessageForm.append(messageField);
                textArea = new StringItem("Messages Received", "\r\n");
                sendMessageForm.append(textArea);
                sendMessageForm.setCommandListener(new CommandListener()
                {
                    public void commandAction(Command command, Displayable display)
                    {
                        if(command.getCommandType() == Command.OK)
                        {
                            SendMessageThread sendMessageThread = new SendMessageThread(uri.getString().trim(), messageField.getString());
                            Thread thread = new Thread(sendMessageThread);
                            thread.start();
                        }
                        else if(command.getCommandType() == Command.EXIT)
                        {
                            exit();
                        }
                    }
                });

                getDisplay().setCurrent(sendMessageForm);
            }
            catch (IllegalArgumentException e3)
            {
                alert("Can not register the  phone: receive IllegalArgumentException: " + e3.getMessage());
            }
            catch (ConnectionNotFoundException e2)
            {
                alert("Can not register the  phone: receive ConnectionNotFoundException");
            }
            catch (IOException e1)
            {
                alert("Can not register the  phone: receive IOException");
            }
            catch (Exception e)
            {
                alert("Can not register the  phone: receive Exception ");
            }
        }
    }

    private Display getDisplay()
    {
        return Display.getDisplay(IjcuBasicPageMessage.this);
    }

    /**
     * Exits the application
     */
    private void exit()
    {
        new CleanUpThread().start();
        try
        {
            Thread.sleep(1000);

            destroyApp(false);
            notifyDestroyed();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * Thread to send a message
     */
    protected class SendMessageThread implements Runnable
    {
        private String remoteUri;;

        private String message;

        public SendMessageThread(String remoteUri, String message)
        {
            this.remoteUri = remoteUri;
            this.message = message;
        }

        public void run()
        {
            sendMessage(remoteUri, message);
        }

        private void sendMessage(String remoteUri, String message)
        {
            if(!isUriValid(remoteUri))
            {
                Alert sendingMessageAlert = new Alert("Warning!");
                sendingMessageAlert.setString("Please enter a valid URI");
                getDisplay().setCurrent(sendingMessageAlert, sendMessageForm);
                return;
            }

            PageMessageListener pageListener = new PageMessageListener()
            {
                /**
                 * Alert the status delivery.
                 */
                public void pageMessageDelivered(PageMessage arg0)
                {
                    appendText("Message was delivered successfully");

                }

                public void pageMessageDeliveryFailed(PageMessage arg0)
                {
                    appendText("Message was not delivered successfully");

                }
            };

            try
            {
                PageMessage page = coreService.createPageMessage(null, remoteUri);
                page.setListener(pageListener);
                page.send(message.getBytes(), contentType);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    private void appendText(String message)
    {
        textArea.setText(textArea.getText() + message + "\r\n");
    }

    /**
     * Check if the input URI is valid
     * 
     * @param uri : input URI
     * @return <code>true</code> the input is valid, <code>false</code> otherwise
     */
    private boolean isUriValid(String uri)
    {
        if(uri.length() == 0 || !(uri.startsWith("sip:") || uri.startsWith("tel:")))
        {
            return false;
        }
        return true;
    }

    private void alert(String message)
    {
        Alert alert = new Alert("Error", "", null, AlertType.ERROR);
        alert.setString(message);
        getDisplay().setCurrent(alert);

        try
        {
            Thread.sleep(1000);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

    /**
     * Receive notifications about changes to the IMS connection.
     */
    class ConnectionStateAdapter implements ConnectionStateListener
    {
        public void imsConnected()
        {

        }

        public void imsDisconnected()
        {

        }
    }

    /**
     * Based on the event received from CoreServiceListener, handle events accordingly.
     */
    private class CoreServiceClientAdapter implements CoreServiceListener
    {
        public CoreServiceClientAdapter()
        {
            super();
        }

        public void pageMessageReceived(CoreService service, PageMessage message)
        {
            String from = "Message from:" + message.getRemoteUserId();
            String content = new String(message.getContent());
            appendText(from);
            appendText(content);
            System.out.println(content);

        }

        public void referenceReceived(CoreService service, Reference reference)
        {

        }

        public void serviceClosed(CoreService service)
        {

        }

        public void sessionInvitationReceived(CoreService service, Session session)
        {

        }

        public void unsolicitedNotifyReceived(CoreService service, Message notify)
        {

        }
    };

}
